/**
 * 
 */
package org.xlab.baseframework.web.data;

import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.xlab.baseframework.domain.SystemCode;
import org.xlab.baseframework.domain.enumerate.EnumDeletedIndentifying;
import org.xlab.baseframework.domain.view.SystemCodeVO;
import org.xlab.baseframework.exception.SystemCodeDuplicateException;
import org.xlab.baseframework.exception.SystemCodeNotFoundException;
import org.xlab.baseframework.service.api.ISystemCodeService;

import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.data.validator.IntegerValidator;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;

/**
 * @author MaKuBEX
 * 
 */
public class CodeEditFormFieldFactory extends DefaultFieldFactory {

	/**
	 * @serialField
	 */
	private static final long serialVersionUID = -3649712427479320925L;
	private static final Logger log = Logger
			.getLogger(CodeEditFormFieldFactory.class);

	private ComboBox category = new ComboBox(SystemCodeVO.FIELD_CATEGORY);

	@Autowired
	@Qualifier("bpf_systemCodeService")
	private ISystemCodeService systemCodeService;

	/**
	 * <p>
	 * 默认构造函数
	 * </p>
	 */
	public CodeEditFormFieldFactory() {
		super();
		this.category.setFilteringMode(ComboBox.FILTERINGMODE_CONTAINS);
		this.category.setNullSelectionAllowed(true);
		this.category.setItemCaptionPropertyId(SystemCodeVO.FIELD_CODE);
		this.category.setItemCaptionMode(ComboBox.ITEM_CAPTION_MODE_PROPERTY);
	}

	/**
	 * @see com.vaadin.ui.DefaultFieldFactory#createField(com.vaadin.data.Item,
	 *      java.lang.Object, com.vaadin.ui.Component)
	 */
	public Field createField(Item item, Object propertyId, Component uiContext) {
		if (propertyId.equals(SystemCodeVO.FIELD_CATEGORY)) {
			try {
				List<SystemCode> allCodes = this.systemCodeService
						.findAllByDeletedInd(EnumDeletedIndentifying.N);
				SystemCode self = this.systemCodeService.findByCode(item
						.getItemProperty(SystemCodeVO.FIELD_CODE).toString(),
						false);
				if (allCodes.contains(self))
					allCodes.remove(self);
				try {
					List<SystemCode> allSubCodes = this.systemCodeService
							.findAllByCategory(self, true, false);
					for (SystemCode c : allSubCodes) {
						if (allCodes.contains(c))
							allCodes.remove(c);
					}
				} catch (SystemCodeNotFoundException e) {
					log.debug("No sub codes found for system code ["
							+ self.getCode() + "].");
				}
				if (allCodes.isEmpty())
					throw new SystemCodeNotFoundException();
				List<SystemCodeVO> voList = this.systemCodeService
						.convertToVOList(allCodes);
				BeanItemContainer<SystemCodeVO> dataSource = new BeanItemContainer<SystemCodeVO>(
						SystemCodeVO.class, voList);
				this.category.setContainerDataSource(dataSource);
				this.category.setValue(item
						.getItemProperty(SystemCodeVO.FIELD_CATEGORY));

			} catch (SystemCodeNotFoundException e) {
				this.category.setContainerDataSource(null);
			} catch (SystemCodeDuplicateException e) {
				e.printStackTrace();
			}
			return this.category;
		} else {
			Field f = super.createField(item, propertyId, uiContext);
			if (propertyId.equals(SystemCodeVO.FIELD_CODE)) {
				f.setReadOnly(true);
			}
			if (propertyId.equals(SystemCodeVO.FIELD_SEQUENCE)) {
				f.addValidator(new IntegerValidator("Please enter an integer!"));
			}
			f.setRequired(true);
			f.setRequiredError("This is a required column! Please fill in some data!");
			f.setInvalidCommitted(false);
			return f;
		}
	}

	/**
	 * @param systemCodeService
	 *            the systemCodeService to set
	 */
	public void setSystemCodeService(ISystemCodeService systemCodeService) {
		this.systemCodeService = systemCodeService;
	}

}
